Subset - 2015 dataset
LifeExpIncomPop15 <- subset( LifeExpIncomPop, LifeExpIncomPop$Year == 2015 )
myPlotlyLayout <- function(){
layout(
## graphic size
with = 700,
height = 700,
### Title
title =list(text = "Association Between Life Expectancy And Income For The Year 2015",
font = list(family = "Times New Roman", # HTML font family
size = 18,
color = "red")),
### legend
legend = list(title = list(text = 'Countries',
font = list(family = "Courier New",
size = 14,
color = "green")),
bgcolor = "ivory",
bordercolor = "navy",
groupclick = "togglegroup", # one of "toggleitem" AND "togglegroup".
orientation = "v" # Sets the orientation of the legend.
),
## margin of the plot
margin = list(
b = 120,
l = 50,
t = 120,
r = 50
),
## Background
plot_bgcolor ='#f7f7f7',
## Axes labels
xaxis = list(
title=list(text = 'Life Expectancy',
font = list(family = 'Arial')),
zerolinecolor = 'red',
zerolinewidth = 2,
gridcolor = 'white'),
yaxis = list(
title=list(text = 'Income',
font = list(family = 'Arial')),
zerolinecolor = 'purple',
zerolinewidth = 2,
gridcolor = 'white'),
## annotations
annotations = list(
x = 80, # between 0 and 1. 0 = left, 1 = right
y = 60, # between 0 and 1, 0 = bottom, 1 = top
font = list(size = 12,
color = "darkred"),
text = "The point size is population of each country",
xref = "paper", # "container" spans the entire `width` of the plot.
# "paper" refers to the width of the plotting area only.
yref = "paper", # same as xref
xanchor = "center", # horizontal alignment with respect to its x position
yanchor = "bottom", # similar to xanchor
showarrow = FALSE ,
## using the following hovertemplate() to add the information of the
## two numerical variable to the hover text.
hovertemplate = paste('<i><b>Income<b></i>: %{y}',
'<br><b>lifeExpe</b>: %{x}',
'<br><b>%{Country}</b>'),
)
)
}
plot_ly(
data = LifeExpIncomPop15,
x = ~lifeExp, # Horizontal axis
y = ~Income, # Vertical axis
color = ~factor(Country), # must be a numeric factor
text = ~Population, # show the Country in the hover text
alpha = 0.9,
size = LifeExpIncomPop15$Population,
type = "scatter",
mode = "markers",
## two numerical variable to the hover text.
hovertemplate = paste('<i><b>Income<b></i>: %{y}',
'<br><b>lifeExp</b>: %{x}')
)
##Animated scatter plot that shows pattern of change in the relationship between life expectancy and income over the years
regions <- countryregions[ , c("name", "region")]
regions<- rename(regions, Country = name )
LifeExpIncomPop.Reg <- merge(regions, LifeExpIncomPop, by = c("Country"))
LifeExpIncomPop.Reg <- na.omit(LifeExpIncomPop.Reg)
library(gapminder)
library(gganimate)
w <- ggplot(gapminder, aes(x = LifeExpIncomPop.Reg$Income,
y = LifeExpIncomPop.Reg$lifeExp,
size = LifeExpIncomPop.Reg$Population,
colour = LifeExpIncomPop.Reg$region)) +
geom_point(alpha = 0.7, show.legend = FALSE) +
scale_colour_manual(values = country_colors) +
#scale_color_manual(values=c("dodgerblue4", "darkolivegreen4","darkorchid3")) +
#scale_color_brewer(palette="Set1") +
scale_size(range = c(2, 12)) +
scale_x_log10() +
# break down the previous single plot by continent
facet_wrap(~region) + # create multiple panels according to the continents
# Here comes the gganimate specific bits
labs(title = 'Year: {frame_time}',
x = 'Income',
y = 'life expectancy') +
transition_time(year) +
ease_aes('linear')
animate(w, renderer = gifski_renderer(),
rewind = TRUE)
Error in `combine_vars()`:
! At least one layer must contain all faceting variables: `region`.
* Plot is missing `region`
* Layer 1 is missing `region`
Backtrace:
1. gganimate::animate(w, renderer = gifski_renderer(), rewind = TRUE)
2. gganimate:::animate.gganim(w, renderer = gifski_renderer(), rewind = TRUE)
3. gganimate:::prerender(plot, nframes_total)
5. gganimate:::ggplot_build.gganim(plot)
6. layout$setup(data, plot$data, plot$plot_env)
7. ggplot2 f(..., self = self)
8. self$facet$compute_layout(data, self$facet_params)
9. ggplot2 f(...)
12. ggplot2::combine_vars(data, params$plot_env, vars, drop = params$drop)
library(gapminder)
p <- ggplot(gapminder, aes(x = LifeExpIncomPop.Reg$Income,
y = LifeExpIncomPop.Reg$lifeExp,
size = LifeExpIncomPop.Reg$Population,
colour = LifeExpIncomPop.Reg$region)) +
geom_point(aes(size = population, ids = region ),
show.legend = FALSE,
alpha = 0.7) +
scale_color_viridis_d() + # color pallets
scale_size(range = c(2, 12)) +
scale_x_log10() +
labs(x = "GDP per capita",
y = "Life expectancy") +
## gganimate command
transition_time(year)
##
anim_save("LifeExp.gif", p)
gas <- "https://raw.githubusercontent.com/datavizualization11/sta553/main/data/POC.csv"
gas.station <- read_csv(gas)
# r sample - simple random sampling in r to pick 500
sample.500 <- gas.station[sample(nrow(gas.station), 500), ]
write.csv(sample.500,"C:\\Users\\agrimamahlawat\\Desktop\\SPRING 22\\sample500gas.csv", row.names = FALSE)
LS0tCnRpdGxlOiAiaHcgMyAtIE1hcmNoIDEzIgphdXRob3I6ICJBZ3JpbWEgTWFobGF3YXQiCmRhdGU6ICIzLzEzLzIwMjIiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDogCiAgICB0b2M6IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCmVkaXRvcl9vcHRpb25zOgogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgoKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCmRpdiNUT0MgbGkgewogICAgbGlzdC1zdHlsZTpub25lOwogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOwogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsKICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsKfQpoMS50aXRsZSB7CiAgZm9udC1zaXplOiAyNHB4OwogIGNvbG9yOiBEYXJrUmVkOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAxOHB4OwogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogIGNvbG9yOiBEYXJrUmVkOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICBmb250LXNpemU6IDE4cHg7CiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgY29sb3I6IERhcmtCbHVlOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDIycHg7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBkYXJrcmVkOwogICAgdGV4dC1hbGlnbjogY2VudGVyOwp9CmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMThweDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IG5hdnk7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE1cHg7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBuYXZ5OwogICAgdGV4dC1hbGlnbjogbGVmdDsKfQoKaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAxOHB4OwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogZGFya3JlZDsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KPC9zdHlsZT4KCgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsKICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKICAgbGlicmFyeSh0aWR5dmVyc2UpCn0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7CiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikKICAgbGlicmFyeShrbml0cikKfQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7CiAgIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpCiAgIGxpYnJhcnkocGxvdGx5KQp9CmlmICghcmVxdWlyZSgiZ2FwbWluZGVyIikpIHsKICAgaW5zdGFsbC5wYWNrYWdlcygiZ2FwbWluZGVyIikKICAgbGlicmFyeShnYXBtaW5kZXIpCn0KaWYgKCFyZXF1aXJlKCJjb2xvdXJwaWNrZXIiKSkgewogICAgaW5zdGFsbC5wYWNrYWdlcygiY29sb3VycGlja2VyIikgICAgICAgICAgICAgIAogICAgbGlicmFyeSgiY29sb3VycGlja2VyIikKfQppZiAoIXJlcXVpcmUoImdnYW5pbWF0ZSIpKSB7CiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnZ2FuaW1hdGUiKSAgICAgICAgICAgICAgCiAgICBsaWJyYXJ5KCJnZ2FuaW1hdGUiKQp9CiMga25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSAiQzovVXNlcnMvNzVDUEVORy9PbmVEcml2ZSAtIFdlc3QgQ2hlc3RlciBVbml2ZXJzaXR5IG9mIFBBL0RvY3VtZW50cyIpCiMga25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSAiQzpcXFNUQTQ5MFxcdzA1IikKIyMKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAKICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICAKICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFRSVUUsICAgCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UpCmBgYAoKCgoKYGBge3J9CmxpYnJhcnkocmVhZHIpICAjIGZvciByZWFkX2NzdgpsaWJyYXJ5KGtuaXRyKSAgIyBmb3Iga2FibGUKCmluY29tZSA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhdGF2aXp1YWxpemF0aW9uMTEvc3RhNTUzL21haW4vZGF0YS9pbmNvbWVfcGVyX3BlcnNvbi5jc3YiCmxpZmUgPC0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9kYXRhdml6dWFsaXphdGlvbjExL3N0YTU1My9tYWluL2RhdGEvbGlmZV9leHBlY3RhbmN5X3llYXJzLmNzdiIKcG9wdWxhdGlvbiA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhdGF2aXp1YWxpemF0aW9uMTEvc3RhNTUzL21haW4vZGF0YS9wb3B1bGF0aW9uX3RvdGFsLmNzdiIKY291bnRyeSA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhdGF2aXp1YWxpemF0aW9uMTEvc3RhNTUzL21haW4vZGF0YS9jb3VudHJpZXNfdG90YWwuY3N2IgoKaW5jb21lcGVycGVyc29uIDwtIHJlYWRfY3N2KGluY29tZSkKbGlmZWV4cGVudGFuY3kgPC0gcmVhZF9jc3YobGlmZSkKcG9wdWxhdGlvbnNpemUgPC0gcmVhZF9jc3YocG9wdWxhdGlvbikKY291bnRyeXJlZ2lvbnMgPC0gcmVhZF9jc3YoY291bnRyeSkKCmBgYAoKIyMgUmVzaGFwZSBkYXRhIHNldDogSW5jb21lIFBlciBQZXJzb24gJiAgTGlmZSBFeHBlY3RhbmN5IGluIFllYXJzCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKaW5jb21lLmxvbmdpdHVkaW5hbCA8LSBpbmNvbWVwZXJwZXJzb24gJT4lCiAgZ2F0aGVyKGtleSA9ICJZZWFyIiwKICAgICAgICAgdmFsdWUgPSAiSW5jb21lIiwKICAgICAgICAgLSBnZW8sCiAgICAgICAgIG5hLnJtID0gVFJVRSkKCmluY29tZS5sb25naXR1ZGluYWw8LSByZW5hbWUoaW5jb21lLmxvbmdpdHVkaW5hbCwgQ291bnRyeSA9IGdlbyApCgpsaWZlZXhwLmxvbmdpdHVkaW5hbCA8LSBsaWZlZXhwZW50YW5jeSAlPiUKICBnYXRoZXIoa2V5ID0gIlllYXIiLAogICAgICAgICB2YWx1ZSA9ICJsaWZlRXhwIiwKICAgICAgICAgLSBnZW8sCiAgICAgICAgIG5hLnJtID0gVFJVRSkKbGlmZWV4cC5sb25naXR1ZGluYWw8LSByZW5hbWUobGlmZWV4cC5sb25naXR1ZGluYWwsIENvdW50cnkgPSBnZW8gKQoKcG9wdWxhdGlvbi5sb25naXR1ZGluYWwgPC0gcG9wdWxhdGlvbnNpemUgJT4lCiAgZ2F0aGVyKGtleSA9ICJZZWFyIiwKICAgICAgICAgdmFsdWUgPSAiUG9wdWxhdGlvbiIsCiAgICAgICAgIC0gZ2VvLAogICAgICAgICBuYS5ybSA9IFRSVUUpCnBvcHVsYXRpb24ubG9uZ2l0dWRpbmFsPC0gcmVuYW1lKHBvcHVsYXRpb24ubG9uZ2l0dWRpbmFsLCBDb3VudHJ5ID0gZ2VvICkKYGBgCgojIyBNZXJnZSB0aGUgZGF0YXNldHMKYGBge3J9CkxpZmVFeHBJbmNvbSA8LSBtZXJnZShpbmNvbWUubG9uZ2l0dWRpbmFsLCBsaWZlZXhwLmxvbmdpdHVkaW5hbCwgYnk9YygiWWVhciIsIkNvdW50cnkiKSkKCiNGaW5hbCBEYXRhc2V0CkxpZmVFeHBJbmNvbVBvcCA8LW1lcmdlKExpZmVFeHBJbmNvbSwgcG9wdWxhdGlvbi5sb25naXR1ZGluYWwsIGJ5PWMoIlllYXIiLCJDb3VudHJ5IikpCmBgYAoKIyMgU3Vic2V0IC0gMjAxNSBkYXRhc2V0CmBgYHtyfQpMaWZlRXhwSW5jb21Qb3AxNSA8LSBzdWJzZXQoIExpZmVFeHBJbmNvbVBvcCwgTGlmZUV4cEluY29tUG9wJFllYXIgPT0gMjAxNSApCmBgYAoKYGBge3J9Cm15UGxvdGx5TGF5b3V0IDwtIGZ1bmN0aW9uKCl7CiAgbGF5b3V0KCAgCiAgICAgICMjIGdyYXBoaWMgc2l6ZQogICAgICB3aXRoID0gNzAwLAogICAgICBoZWlnaHQgPSA3MDAsCiAgICAgICMjIyBUaXRsZSAKICAgICAgdGl0bGUgPWxpc3QodGV4dCA9ICJBc3NvY2lhdGlvbiBCZXR3ZWVuIExpZmUgRXhwZWN0YW5jeSBBbmQgSW5jb21lIEZvciBUaGUgWWVhciAyMDE1IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9udCA9IGxpc3QoZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIsICAjIEhUTUwgZm9udCBmYW1pbHkgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDE4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJyZWQiKSksIAogICAgICAjIyMgbGVnZW5kCiAgICAgIGxlZ2VuZCA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQgPSAnQ291bnRyaWVzJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9udCA9IGxpc3QoZmFtaWx5ID0gIkNvdXJpZXIgTmV3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gMTQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJncmVlbiIpKSwKICAgICAgICAgICAgICAgICAgICBiZ2NvbG9yID0gIml2b3J5IiwKICAgICAgICAgICAgICAgICAgICBib3JkZXJjb2xvciA9ICJuYXZ5IiwKICAgICAgICAgICAgICAgICAgICBncm91cGNsaWNrID0gInRvZ2dsZWdyb3VwIiwgICMgb25lIG9mICAidG9nZ2xlaXRlbSIgQU5EICJ0b2dnbGVncm91cCIuCiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb24gPSAidiIgICMgU2V0cyB0aGUgb3JpZW50YXRpb24gb2YgdGhlIGxlZ2VuZC4KICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICApLAogICAgICAjIyBtYXJnaW4gb2YgdGhlIHBsb3QKICAgICAgbWFyZ2luID0gbGlzdCgKICAgICAgICAgICAgICBiID0gMTIwLAogICAgICAgICAgICAgIGwgPSA1MCwKICAgICAgICAgICAgICB0ID0gMTIwLAogICAgICAgICAgICAgIHIgPSA1MAogICAgICApLAogICAgICAjIyBCYWNrZ3JvdW5kCiAgICAgIHBsb3RfYmdjb2xvciA9JyNmN2Y3ZjcnLCAKICAgICAgIyMgQXhlcyBsYWJlbHMKICAgICAgICAgICAgIHhheGlzID0gbGlzdCggCiAgICAgICAgICAgICAgICAgICAgdGl0bGU9bGlzdCh0ZXh0ID0gJ0xpZmUgRXhwZWN0YW5jeScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb250ID0gbGlzdChmYW1pbHkgPSAnQXJpYWwnKSksCiAgICAgICAgICAgICAgICAgICAgemVyb2xpbmVjb2xvciA9ICdyZWQnLCAKICAgICAgICAgICAgICAgICAgICB6ZXJvbGluZXdpZHRoID0gMiwgCiAgICAgICAgICAgICAgICAgICAgZ3JpZGNvbG9yID0gJ3doaXRlJyksIAogICAgICAgICAgICB5YXhpcyA9IGxpc3QoIAogICAgICAgICAgICAgICAgICAgIHRpdGxlPWxpc3QodGV4dCA9ICdJbmNvbWUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9udCA9IGxpc3QoZmFtaWx5ID0gJ0FyaWFsJykpLAogICAgICAgICAgICAgICAgICAgIHplcm9saW5lY29sb3IgPSAncHVycGxlJywgCiAgICAgICAgICAgICAgICAgICAgemVyb2xpbmV3aWR0aCA9IDIsIAogICAgICAgICAgICAgICAgICAgIGdyaWRjb2xvciA9ICd3aGl0ZScpLAogICAgICAgIyMgYW5ub3RhdGlvbnMKICAgICAgIGFubm90YXRpb25zID0gbGlzdCggIAogICAgICAgICAgICAgICAgICAgICB4ID0gODAsICAgIyBiZXR3ZWVuIDAgYW5kIDEuIDAgPSBsZWZ0LCAxID0gcmlnaHQKICAgICAgICAgICAgICAgICAgICAgeSA9IDYwLCAgICMgYmV0d2VlbiAwIGFuZCAxLCAwID0gYm90dG9tLCAxID0gdG9wCiAgICAgICAgICAgICAgICAgIGZvbnQgPSBsaXN0KHNpemUgPSAxMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiZGFya3JlZCIpLCAgIAogICAgICAgICAgICAgICAgICB0ZXh0ID0gIlRoZSBwb2ludCBzaXplIGlzIHBvcHVsYXRpb24gb2YgZWFjaCBjb3VudHJ5IiwgICAKICAgICAgICAgICAgICAgICAgeHJlZiA9ICJwYXBlciIsICAjICJjb250YWluZXIiIHNwYW5zIHRoZSBlbnRpcmUgYHdpZHRoYCBvZiB0aGUgcGxvdC4gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAicGFwZXIiIHJlZmVycyB0byB0aGUgd2lkdGggb2YgdGhlIHBsb3R0aW5nIGFyZWEgb25seS4gIAogICAgICAgICAgICAgICAgICB5cmVmID0gInBhcGVyIiwgICMgIHNhbWUgYXMgeHJlZgogICAgICAgICAgICAgICB4YW5jaG9yID0gImNlbnRlciIsICMgIGhvcml6b250YWwgYWxpZ25tZW50IHdpdGggcmVzcGVjdCB0byBpdHMgeCBwb3NpdGlvbgogICAgICAgICAgICAgICB5YW5jaG9yID0gImJvdHRvbSIsICMgIHNpbWlsYXIgdG8geGFuY2hvciAgCiAgICAgICAgICAgICBzaG93YXJyb3cgPSBGQUxTRSAgLAogICAgICAgICAgICAgIyMgdXNpbmcgdGhlIGZvbGxvd2luZyBob3ZlcnRlbXBsYXRlKCkgdG8gYWRkIHRoZSBpbmZvcm1hdGlvbiBvZiB0aGUKICAgICAjIyB0d28gbnVtZXJpY2FsIHZhcmlhYmxlIHRvIHRoZSBob3ZlciB0ZXh0LgogICAgIGhvdmVydGVtcGxhdGUgPSBwYXN0ZSgnPGk+PGI+SW5jb21lPGI+PC9pPjogJXt5fScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnI+PGI+bGlmZUV4cDwvYj46ICAle3h9JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj48Yj4le0NvdW50cnl9PC9iPicpLAogICAgICAgICAgICkKICApCn0KYGBgCgpgYGB7cn0KcGxvdF9seSgKICAgIGRhdGEgPSBMaWZlRXhwSW5jb21Qb3AxNSwKICAgIHggPSB+bGlmZUV4cCwgICMgSG9yaXpvbnRhbCBheGlzIAogICAgeSA9IH5JbmNvbWUsICAgIyBWZXJ0aWNhbCBheGlzIAogICAgY29sb3IgPSB+ZmFjdG9yKENvdW50cnkpLCAgIyBtdXN0IGJlIGEgbnVtZXJpYyBmYWN0b3IKICAgICB0ZXh0ID0gflBvcHVsYXRpb24sICAjIHNob3cgdGhlIENvdW50cnkgaW4gdGhlIGhvdmVyIHRleHQKCiAgICAgYWxwaGEgID0gMC45LAogICAgIHNpemUgPSBMaWZlRXhwSW5jb21Qb3AxNSRQb3B1bGF0aW9uLAogICAgIHR5cGUgPSAic2NhdHRlciIsCiAgICAgbW9kZSA9ICJtYXJrZXJzIiwKICAgICAgICAjIyB0d28gbnVtZXJpY2FsIHZhcmlhYmxlIHRvIHRoZSBob3ZlciB0ZXh0LgogICAgIGhvdmVydGVtcGxhdGUgPSBwYXN0ZSgnPGk+PGI+SW5jb21lPGI+PC9pPjogJXt5fScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnI+PGI+bGlmZUV4cDwvYj46ICAle3h9JykKICAgKSAKYGBgCiMjQW5pbWF0ZWQgc2NhdHRlciBwbG90IHRoYXQgc2hvd3MgcGF0dGVybiBvZiBjaGFuZ2UgaW4gdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGxpZmUgZXhwZWN0YW5jeSBhbmQgaW5jb21lIG92ZXIgdGhlIHllYXJzCmBgYHtyfQpyZWdpb25zIDwtIGNvdW50cnlyZWdpb25zWyAsIGMoIm5hbWUiLCAicmVnaW9uIildICAKcmVnaW9uczwtIHJlbmFtZShyZWdpb25zLCBDb3VudHJ5ID0gbmFtZSApIAoKTGlmZUV4cEluY29tUG9wLlJlZyA8LSBtZXJnZShyZWdpb25zLCBMaWZlRXhwSW5jb21Qb3AsIGJ5ID0gYygiQ291bnRyeSIpKQoKTGlmZUV4cEluY29tUG9wLlJlZyA8LSBuYS5vbWl0KExpZmVFeHBJbmNvbVBvcC5SZWcpCgpgYGAKCmBgYHtyfQpsaWJyYXJ5KGdhcG1pbmRlcikKbGlicmFyeShnZ2FuaW1hdGUpCgp3IDwtIGdncGxvdChnYXBtaW5kZXIsIGFlcyh4ID0gTGlmZUV4cEluY29tUG9wLlJlZyRJbmNvbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gTGlmZUV4cEluY29tUG9wLlJlZyRsaWZlRXhwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IExpZmVFeHBJbmNvbVBvcC5SZWckUG9wdWxhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gTGlmZUV4cEluY29tUG9wLlJlZyRyZWdpb24pKSArCiAgICAgICAgICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNywgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgICAgICAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gY291bnRyeV9jb2xvcnMpICsKICAgICAgICAgICAjc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCJkb2RnZXJibHVlNCIsICJkYXJrb2xpdmVncmVlbjQiLCJkYXJrb3JjaGlkMyIpKSArCiAgICAgICAgICAgI3NjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJTZXQxIikgKwogICAgICAgICAgIHNjYWxlX3NpemUocmFuZ2UgPSBjKDIsIDEyKSkgKwogICAgICAgICAgIHNjYWxlX3hfbG9nMTAoKSArCiAgICAgICAgICAgIyBicmVhayBkb3duIHRoZSBwcmV2aW91cyBzaW5nbGUgcGxvdCBieSBjb250aW5lbnQgCiAgICAgICAgICAgZmFjZXRfd3JhcCh+cmVnaW9uKSArICAgICAjIGNyZWF0ZSBtdWx0aXBsZSBwYW5lbHMgYWNjb3JkaW5nIHRvIHRoZSBjb250aW5lbnRzCiAgICAgICAgICAgIyBIZXJlIGNvbWVzIHRoZSBnZ2FuaW1hdGUgc3BlY2lmaWMgYml0cwogICAgICAgICAgIGxhYnModGl0bGUgPSAnWWVhcjoge2ZyYW1lX3RpbWV9JywgCiAgICAgICAgICAgICAgICAgICAgeCA9ICdJbmNvbWUnLAogICAgICAgICAgICAgICAgICAgIHkgPSAnbGlmZSBleHBlY3RhbmN5JykgKwogICAgICAgICAgIHRyYW5zaXRpb25fdGltZSh5ZWFyKSArCiAgICAgICAgICAgZWFzZV9hZXMoJ2xpbmVhcicpCgphbmltYXRlKHcsIHJlbmRlcmVyID0gZ2lmc2tpX3JlbmRlcmVyKCksCiAgICAgICAgICByZXdpbmQgPSBUUlVFKQoKYGBgCmBgYHtyfQpsaWJyYXJ5KGdhcG1pbmRlcikKCnAgPC0gZ2dwbG90KGdhcG1pbmRlciwgYWVzKHggPSBMaWZlRXhwSW5jb21Qb3AuUmVnJEluY29tZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBMaWZlRXhwSW5jb21Qb3AuUmVnJGxpZmVFeHAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gTGlmZUV4cEluY29tUG9wLlJlZyRQb3B1bGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBMaWZlRXhwSW5jb21Qb3AuUmVnJHJlZ2lvbikpICsKICAgICAgICBnZW9tX3BvaW50KGFlcyhzaXplID0gcG9wdWxhdGlvbiwgaWRzID0gcmVnaW9uICksCiAgICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgIGFscGhhID0gMC43KSArCiAgICAgICAgc2NhbGVfY29sb3JfdmlyaWRpc19kKCkgKyAgICAgICMgY29sb3IgcGFsbGV0cyAKICAgICAgICBzY2FsZV9zaXplKHJhbmdlID0gYygyLCAxMikpICsKICAgICAgICBzY2FsZV94X2xvZzEwKCkgKwogICAgICAgIGxhYnMoeCA9ICJHRFAgcGVyIGNhcGl0YSIsIAogICAgICAgICAgICAgeSA9ICJMaWZlIGV4cGVjdGFuY3kiKSArCiAgICAgICAgIyMgZ2dhbmltYXRlIGNvbW1hbmQKICAgICAgIHRyYW5zaXRpb25fdGltZSh5ZWFyKQojIyAKYW5pbV9zYXZlKCJMaWZlRXhwLmdpZiIsIHApCmBgYAoKYGBge3J9CmdhcyA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RhdGF2aXp1YWxpemF0aW9uMTEvc3RhNTUzL21haW4vZGF0YS9QT0MuY3N2IgoKZ2FzLnN0YXRpb24gPC0gcmVhZF9jc3YoZ2FzKQoKIyByIHNhbXBsZSAtIHNpbXBsZSByYW5kb20gc2FtcGxpbmcgaW4gciB0byBwaWNrIDUwMApzYW1wbGUuNTAwIDwtIGdhcy5zdGF0aW9uW3NhbXBsZShucm93KGdhcy5zdGF0aW9uKSwgNTAwKSwgXQoKd3JpdGUuY3N2KHNhbXBsZS41MDAsIkM6XFxVc2Vyc1xcYWdyaW1hbWFobGF3YXRcXERlc2t0b3BcXFNQUklORyAyMlxcc2FtcGxlNTAwZ2FzLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKCgoKCgoK